package com.hmkj.core.api.ufx.mc;

import com.hmkj.boot.utils.SpringContextUtils;
import com.hmkj.core.api.ufx.model.res.DealPush;
import com.hmkj.core.api.ufx.model.res.EntrustPush;
import com.hmkj.core.constant.CacheID;
import com.hmkj.core.constant.ConfigNID;
import com.hmkj.core.model.quote.RealTimeData;
import com.hmkj.core.model.quote.SimpleRealData;
import com.hmkj.core.po.commo.Commo;
import com.hmkj.core.service.cache.RedisService;
import com.hmkj.core.service.order.OrderService;
import com.hmkj.core.service.order.OrderSimulateService;
import com.hmkj.core.service.risk.RiskParamService;
import com.hundsun.mcapi.interfaces.ISubCallback;
import com.hundsun.mcapi.subscribe.MCSubscribeParameter;
import com.hundsun.t2sdk.interfaces.share.dataset.IDataset;
import com.hundsun.t2sdk.interfaces.share.event.IEvent;
import com.xiaoleilu.hutool.util.StrUtil;
import com.xiaoleilu.hutool.util.ThreadUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

@Slf4j
public class MCCallback implements ISubCallback {

    private static RedisService redisService = SpringContextUtils.getBean(RedisService.class);
    private static RiskParamService riskParamService = SpringContextUtils.getBean(RiskParamService.class);

    private static OrderService orderService = SpringContextUtils.getBean(OrderService.class);
    private static OrderSimulateService orderSimulateService = SpringContextUtils.getBean(OrderSimulateService.class);

    // 系统标识
    private static String prefix = redisService.get(ConfigNID.SYS_FLAG) + "_";

    @Override
    public void OnReceived(String paramString, IEvent paramIEvent) {
        try {
            StringBuilder sb = new StringBuilder();
            //获取结果集
            IDataset ds = paramIEvent.getEventDatas().getDataset(0);
            int columnCount = ds.getColumnCount();
            //打印结果集标注
            for (int j = 1; j <= columnCount; j++) {
                sb.append(ds.getColumnName(j));
                sb.append("|");
            }
            //遍历单个结果集记录，遍历前首先将指针置到开始
            ds.beforeFirst();
            while (ds.hasNext()) {
                sb.append("\n");
                ds.next();
                //打印结果集数据
                for (int j = 1; j <= columnCount; j++) {
                    sb.append(ds.getString(j)).append("|");
                }
            }


            if ("ovfutu.trade_push".equals(paramString) || "futu.trade_push".equals(paramString)) {
                // 整理推送数据
                Map<String, String> datas = analysisData(sb);
                // 交易主推
                switch (datas.get("msg_type")) {
                    case "1001":
                        // 期货委托回报，推送委托回报队列处理
                        if (StrUtil.isNotBlank(datas.get("entrust_reference")) && datas.get("entrust_reference").startsWith(prefix)) {
                            log.info("委托推送数据：\n{}", sb.toString());
                            datas.put("entrust_reference", datas.get("entrust_reference").replace(prefix, ""));
                            redisService.push(CacheID.QUEUE_ENTRUST_PUSH, EntrustPush.buildData(datas, paramString));
                        } else {
                            log.error("其他平台委托推送数据，舍弃处理：{}", datas.get("entrust_reference") + "_" + datas.get("futu_entrust_no"));
                        }
                        break;
                    case "1002":
                        // 期货成交回报，推送成交回报队列处理
                        if (StrUtil.isNotBlank(datas.get("entrust_reference")) && datas.get("entrust_reference").startsWith(prefix)) {
                            log.info("成交推送数据：\n{}", sb.toString());
                            datas.put("entrust_reference", datas.get("entrust_reference").replace(prefix, ""));
                            redisService.push(CacheID.QUEUE_DEAL_PUSH, DealPush.buildData(datas, paramString));
                        } else {
                            log.error("其他平台成交推送数据，舍弃处理：{}", datas.get("entrust_reference") + "_" + datas.get("futu_entrust_no") + "_" + datas.get("futu_business_no"));
                        }
                        break;
                    case "1010":
                        // 期货资金变动通知，推送资金变动队列处理（暂无）
                        break;
                    default:
                        break;
                }
            } else if ("ofutu.quotation_push".equals(paramString) || "futu.quotation_push".equals(paramString)) {
//                if ("ofutu.quotation_push".equals(paramString) ){
//                    log.info("OUT");
//                }else if ("futu.quotation_push".equals(paramString)){
//                    log.info("IN");
//                }else {
//                    log.info("UNKNOW");
//                }
                // 整理推送数据
                Map<String, String> datas = analysisData(sb);
                // 行情主推
                RealTimeData realTimeData = RealTimeData.buildData(datas, paramString);
                // 获取期货品种信息
                Commo commo = redisService.get(CacheID.COMMO_CODE_PREFIX + realTimeData.getCt(), Commo.class);
                if (commo != null && realTimeData.getCc().equals(riskParamService.getContractNo(commo.getId()))) {
                    // 缓存实时行情数据
                    redisService.put(CacheID.QUOTE_REAL_PREFIX + commo.getId(), realTimeData);
                    // 期货实时简要行情缓存MAP
                    redisService.mapPut(CacheID.QUOTE_SIMPLEREAL_MAP, commo.getId().toString(), SimpleRealData.buildData(realTimeData));

                    // 限价策略行情驱动下单
                    ThreadUtil.execute(() -> orderService.doLimitOrderTrade(commo.getId(), realTimeData.getNp()));
                    // 止盈止损触发平仓
                    ThreadUtil.execute(() -> orderService.doCoverByLostProfit(realTimeData.getNp(), realTimeData.getCt()));

                    //行情主推触发模拟订单相关操作
                    // 限价策略行情驱动下单
                    ThreadUtil.execute(() -> orderSimulateService.doLimitOrderTrade(commo.getId(), realTimeData.getNp()));
                    // 止盈止损触发平仓
                    ThreadUtil.execute(() -> orderSimulateService.doCoverByLostProfit(realTimeData.getNp(), realTimeData.getCt()));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("解析推送参数失败,错误消息：{}", e.getMessage());
        }
    }

    /**
     * 整理推送数据
     *
     * @param sb
     * @return
     */
    private Map<String, String> analysisData(StringBuilder sb) {
        // 接收数据数组
        String[] keys = sb.toString().split("\n")[0].split("\\|");
        String[] vals = sb.toString().split("\n")[1].split("\\|");

        Map<String, String> datas = new HashMap<>();
        for (int i = 0; i < keys.length; i++) {
            datas.put(keys[i], vals[i]);
        }
        return datas;
    }

    @Override
    public void OnRecvTickMsg(MCSubscribeParameter paramMCSubscribeParameter, String paramString) {
        // TODO Auto-generated method stub
    }

}
